package com.yn.sys.service;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.yn.sys.dao.DeviceDao;
import com.yn.sys.tools.FileUtils;
import com.yn.sys.tools.SerialPortTool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DeviceService {

    @Autowired
    private DeviceDao deviceDao;

    private JSONArray configInfos = FileUtils.readFileToJson();

    @Value("${yn.serial.port.pname}")
    private String pname;

    public void pushDataToIot() {
        for (Object item : configInfos) {
            // 配置信息
            JSONObject configInfo = (JSONObject) item;
            // 整理数据
            organizeData(configInfo);
            // 发送数据
            sendMonitorRecordByEid(configInfo);
        }
    }

    // 整理数据
    public void organizeData(JSONObject configInfo){
        if (pname.equals("LiJiaHe")){
            // 整理数据
            JSONArray iotDatas = new JSONArray();
            int eid = configInfo.getIntValue("eid");
            // 逻辑传感器数据
            JSONArray oldDataList = deviceDao.queryOldDataByEid(eid);
            if (oldDataList == null || oldDataList.isEmpty()) {
                log.error("逻辑传感器数据: eid = {} query data is Empty!", eid);
                //return;
            } else {
                for (Object item : oldDataList) {
                    JSONObject oldData = (JSONObject) item;
                    iotDatas.add(oldData);
                }
            }
            // 取实物传感器数据
            oldDataList = deviceDao.queryOldDataByPid(eid);
            if (oldDataList == null || oldDataList.isEmpty()) {
                log.error("取实物传感器数据: eid = {} query data is Empty!", eid);
                //return;
            } else {
                for (Object item : oldDataList) {
                    JSONObject oldData = (JSONObject) item;
                    iotDatas.add(oldData);
                }
            }
            if(!iotDatas.isEmpty()){
                iotDatas = mergedDatas(iotDatas);
                for (Object iotData : iotDatas) {
                    deviceDao.insertIotData((JSONObject) iotData);
                }
            }
        }
    }

    private JSONArray mergedDatas(JSONArray jsonArray){
        // 用于存储合并结果的Map，键是eid和rtime的组合，值是新的JSONObject
        Map<String, JSONObject> mergedMap = new HashMap<>();
        for (Object obj : jsonArray) {
            JSONObject jsonObject = (JSONObject) obj;
            String eid = jsonObject.getString("eid");
            String rtime = jsonObject.getString("rtime");
            String dname = jsonObject.getString("dname");
            double dvalue = jsonObject.getDouble("dvalue");
            String key = eid + "_" + rtime; // 使用eid和rtime的组合作为键

            JSONObject mergedObj = mergedMap.get(key);
            if (mergedObj == null) {
                // 如果没有找到合并的JSONObject，则创建一个新的
                mergedObj = new JSONObject();
                mergedObj.put("eid", eid);
                mergedObj.put("rtime", rtime);
                mergedMap.put(key, mergedObj);
            }
            switch (dname){
                case "测点水位":
                    mergedObj.put("f0", dvalue);
                    break;
                case "压力":
                    mergedObj.put("f1", dvalue);
                    break;
                case "温度":
                    mergedObj.put("f2", dvalue);
                    break;
            }
        }

        // 输出合并后的结果
        JSONArray mergedArray = new JSONArray();
        for (JSONObject mergedObj : mergedMap.values()) {
//            System.out.println(mergedObj.toString());
            if(mergedObj.containsKey("f0") && mergedObj.containsKey("f1")&& mergedObj.containsKey("f2")){
                mergedArray.add(mergedObj);
            }
        }
        return mergedArray;
    }

    private void sendMonitorRecordByEid(JSONObject configInfo) {
        int eid = configInfo.getIntValue("eid");
        String tableName = configInfo.getString("tableName");
        // 根据eid 获取monit数据
        JSONArray mrDataList = deviceDao.queryMonitorRecordByEid(tableName, eid);
        if (mrDataList == null || mrDataList.isEmpty()) {
            log.error("eid = {} query data is Empty!", eid);
            return;
        }
        // 转换数据
        for (Object item : mrDataList) {
            JSONObject mrData = (JSONObject) item;
            JSONObject fmtDatas = convertDataFormat(configInfo, mrData);
            // 发送数据
            SerialPortTool.addMsgInfo(JSONObject.toJSONString(fmtDatas, JSONWriter.Feature.WriteMapNullValue));
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                log.error("InterruptedException {}", e);
            }
        }
        updateIotInfoTime(mrDataList.get(mrDataList.size() - 1));
    }

    private JSONObject convertDataFormat(JSONObject configInfo, JSONObject mrData) {
        JSONObject deviceTemp = new JSONObject();
        JSONArray colAttrList = configInfo.getJSONArray("col_attr");
        String pname = configInfo.getString("pname");
        // 拼接设备 : 数据
        deviceTemp.put("serviceId", configInfo.getString("serviceId"));
        deviceTemp.put("deviceId", configInfo.getString("deviceId"));
        deviceTemp.put("secret", configInfo.getString("secret"));

        JSONObject dataTemp = new JSONObject();
        for (Object colAttrItem : colAttrList) {
            JSONObject colAttrInfo = (JSONObject) colAttrItem;

            String key = colAttrInfo.getString("iot_attribute");
            String type = colAttrInfo.getString("type");

            if (StringUtils.equalsIgnoreCase(type, "double")) {
                dataTemp.put(key, mrData.getDouble(colAttrInfo.getString("table_column")));
            } else {
                dataTemp.put(key, mrData.getString(colAttrInfo.getString("table_column")));
            }
        }
        deviceTemp.put("data", dataTemp);
        return deviceTemp;

    }

    public void handleAcceptMsg(String msg) {
        log.error("accept msg is {}", msg);
    }

    public void updateIotInfoTime(Object info){
        deviceDao.updateIotInfoTime(info);
    }

    @PostConstruct
    public void initEidLastTime(){
        List<Integer> configEids = new ArrayList<>();
        for (Object item : configInfos) {
            // 配置信息
            JSONObject configInfo = (JSONObject) item;
            configEids.add(configInfo.getIntValue("eid"));
        }
        // 获取存放时间的数据库ID
        JSONArray iotInfoEidsArr = deviceDao.queryAllIotInfo();
        List<Integer> iotEidList = iotInfoEidsArr.stream().map(item -> {
            JSONObject iotInfoEid = (JSONObject) item;
            return iotInfoEid.getIntValue("eid");
        }).collect(Collectors.toList());

        // 组装iotInfo默认数据
        JSONArray defaultIotInfos = new JSONArray();
        for (Integer configEid : configEids) {
            if (iotEidList.contains(configEid)) {
                continue;
            }

            JSONObject defaultIotInfo = new JSONObject();
            defaultIotInfo.put("eid", configEid);
            defaultIotInfos.add(defaultIotInfo);
        }

        if (!defaultIotInfos.isEmpty()) {
            // 组装iotInfo默认数据
            log.error("register time eid is {}", JSONObject.toJSONString(defaultIotInfos) );
            deviceDao.insertInfoIotInfos(defaultIotInfos);
        }
    }

}
